# -*- coding: utf-8 -*-
import os,sys,re
import time
from env import serial
from serial.tools import list_ports
class UARTDevice(object):
    __version__ = '2.1'
    def __init__(self, port, log, br, timeout):
        # 
        self.log = None
        self._device = None
        if re.match(r'^\d$', port):
            self.portname = getUartNameByIdx(port)
        else:
            self.portname = port
        try:
            self._device = serial.Serial(self.portname, baudrate=br, timeout=0.2)
            self.log = log
            self.usbtimeout = timeout
            self.log.write('SerialPort:' + str(self.portname))
            self.log.write('Debug usbtimeout:' + str(timeout))
        except Exception as e:
            self._device = None
            self.log = None
            raise e

    def __del__(self):
        try:
            if self._device:
                self.close()
        except Exception as e:
            pass

    @classmethod
    def list_device(cls):
        return tuple([d.device for d in list_ports.comports()])

    def open(self):
        if not self._device.isOpen():
            self.log.write('to open uart: ' + self.portname)
            self._device.open()
            self.log.write('uart is open')

    def redo_open(self):
        self.close()
        self.open()

    def sendAndRead(self, cmd, prefix='UART>',delemiter='fixture_done'):
        return self.query(cmd,prefix,delemiter)

    def query(self, cmd, prefix='UART>',delemiter='fixture_done'):
        self.log.write('Start Run UART sendAndRead \"{}\"'.format(cmd))
        try:
            # 2. to open uart
            if not self._device.isOpen():
                self.log.write('to open uart: ' + self.portname)
                self._device.open()
                self.log.write('uart is open')
            # 3. send command
            cmd_str = cmd
            self._device.write(cmd_str.encode('utf-8'))
            self.log.write(prefix + str(cmd))
            # 4. read response
            self._device.flushOutput()
            #response = self._device.readall()
            time_end = time.time() + self.usbtimeout
            self.log.write("debug usbtimeout1:" + str(self.usbtimeout))
            response = ''
            while True:
                try:
                    _lineByte = self._device.readline()
                    _lineResp = _lineByte.decode('utf-8')
                except Exception as e:
                    _lineResp = ''
                    self.log.write(_lineByte)
                    self.log.write(e)
                response += _lineResp if _lineResp else ''
                if _lineResp:
                    self.log.write(prefix + str(_lineResp))
                if "PASS " + cmd in response:
                    break
                if delemiter in response:
                    break
                if time.time() > time_end:
                    break
            return response
        except Exception as e:
            self.log.writeError("UART {}, WRITE CMD {}, Error: {}".format(self.portname, cmd, str(e)))
            raise e

    def close(self):
        if self._device.isOpen():
            self.log.write('to close uart {}'.format(self.portname))
            self._device.close()
            self.log.write('uart is closed')


